﻿/*******************************************************************************
 * Copyright © 2016-2020 北京网非科技有限公司 版权所有
 * Author: 北京网非科技有限公司
 * Description: 网非快速开发平台NET
 * Website：http://www.wfdot.com
*********************************************************************************/
using CubicFWNet.Common;
using CubicFWNet.Data.SystemManage;
using CubicFWNet.Data.SystemManage.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CubicFWNet.Application.SystemManage
{
    public class ModuleApp
    {

        private readonly ModuleRepository _service = new ModuleRepository();
        private readonly RelevanceRepository _relevanceRepository = new RelevanceRepository();

        //private readonly RelevanceRepository _relevanceRepository;
        public List<Module> GetList()
        {
            return _service.IQueryable().OrderBy(t => t.SortNo).ToList();
        }

        public Module GetForm(Guid id)
        {
            return _service.FindEntity(id);
        }

        public int AddOrUpdate(Module module)
        {
            ChangeModuleCascade(module);
            if (module.Id == Guid.Empty)
            {
                module.Id = Guid.NewGuid();
                return _service.Insert(module);
            }
            else
            {
                return _service.Update(module);
            }
        }

        public ResponseResult Delete(Guid id)
        {
            var del = _service.FindEntity(id);
            if (del == null)
                return new ResponseResult { Status = ResultType.error.ToString(), Message = "未找到该数据", Data = id }; 
            var ids = GetSubIds(id);
            _service.Delete(u => u.CascadeId.Contains(del.CascadeId));
            return new ResponseResult { Status = ResultType.success.ToString(), Data = id };
        }

        /// <summary>
        /// 加载一个节点下面的所有
        /// </summary>
        public IEnumerable<Module> Load()
        {
            if (!GetModulesQuery().Any()) //用户不能访问任何模块
            {
                return null;
            }
            var query = GetModulesQuery();
            int total = query.Count();
            var modules = query.OrderBy(u => u.CascadeId);
            return modules;
        }

        /// <summary>
        /// 得出登录用户拥有的模块
        /// </summary>
        private IQueryable<Module> GetModulesQuery()
        {
            var _user = OperatorProvider.Provider.GetCurrent();
            if (_user.IsSystem)
            {
                return _service.IQueryable();
            }
            var _userRoleIds = _relevanceRepository.IQueryable(u => u.FirstId == _user.UserId && u.Type == "UserRole").Select(u => u.SecondId).ToList();
            var moduleIds = _relevanceRepository.IQueryable(
                u =>
                    (u.FirstId == _user.UserId && u.Type == "UserModule") ||
                    (u.Type == "RoleModule" && _userRoleIds.Contains(u.FirstId))).Select(u => u.SecondId).ToList();
            return _service.IQueryable(u => moduleIds.Contains(u.Id)).OrderBy(u => u.SortNo);
        }

        /// <summary>
        /// 得出 某一 用户拥有的模块
        /// </summary>
        public List<Module> GetModulesQuery(Guid userId)
        {
            var _userRoleIds = _relevanceRepository.IQueryable(u => u.FirstId == userId && u.Type == "UserRole").Select(u => u.SecondId).ToList();
            var moduleIds = _relevanceRepository.IQueryable(
                u =>
                    (u.FirstId == userId && u.Type == "UserModule") ||
                    (u.Type == "RoleModule" && _userRoleIds.Contains(u.FirstId))).Select(u => u.SecondId).ToList();
            return _service.IQueryable(u => moduleIds.Contains(u.Id)).OrderBy(u => u.SortNo).ToList();
        }

        #region 用户/角色分配模块

        /// <summary>
        /// 加载特定用户的模块
        /// </summary>
        /// <param name="userId">The user unique identifier.</param>
        public List<Module> LoadForUser(Guid userId, bool IsSystem = false)
        {
            if (IsSystem)
            {
                return _service.IQueryable().ToList();
            }
            //用户角色
            var userRoleIds =
                _relevanceRepository.IQueryable(u => u.FirstId == userId && u.Type == "UserRole").Select(u => u.SecondId).ToList();

            //用户角色与自己分配到的模块ID
            var moduleIds =
                _relevanceRepository.IQueryable(
                    u =>
                        (u.FirstId == userId && u.Type == "UserModule") ||
                        (u.Type == "RoleModule" && userRoleIds.Contains(u.FirstId))).Select(u => u.SecondId).ToList();

            //var moduleIds =
            //    _relevanceRepository.Find(u => u.FirstId == userId && u.Key == "UserModule")
            //        .Select(u => u.SecondId)
            //        .ToList();
            if (!moduleIds.Any()) return new List<Module>();
            return _service.IQueryable(u => moduleIds.Contains(u.Id)).OrderBy(a => a.SortNo).ToList();
        }

        ///// <summary>
        ///// 加载特定角色的模块
        ///// </summary>
        ///// <param name="roleId">The role unique identifier.</param>
        //public List<Module> LoadForRole(Guid roleId)
        //{
        //    var moduleIds =
        //        _relevanceRepository.Find(u => u.FirstId == roleId && u.Key == "RoleModule")
        //            .Select(u => u.SecondId)
        //            .ToList();
        //    if (!moduleIds.Any()) return new List<Module>();
        //    return _service.Find(u => moduleIds.Contains(u.Id)).ToList();
        //}

        #endregion 用户/角色分配模块

        #region 私有方法

        //根据同一级中最大的语义ID

        private Guid[] GetSubIds(Guid parentId)
        {
            if (parentId == Guid.Empty)
                return GetList().Select(u => u.Id).ToArray();
            var parent = _service.FindEntity(parentId);
            var orgs = _service.IQueryable(u => u.CascadeId.Contains(parent.CascadeId)).Select(u => u.Id).ToArray();
            return orgs;
        }

        //修改对象的级联ID
        private void ChangeModuleCascade(Module module)
        {
            string cascadeId;
            int currentCascadeId = 1;  //当前结点的级联节点最后一位
            var sameLevels = _service.IQueryable(o => o.ParentId == module.ParentId && o.Id != module.Id);
            foreach (var obj in sameLevels)
            {
                int objCascadeId = int.Parse(obj.CascadeId.Split('.').Last());
                if (currentCascadeId <= objCascadeId) currentCascadeId = objCascadeId + 1;
            }

            if (module.ParentId != null && module.ParentId != Guid.Empty)
            {
                var parentOrg = _service.FindEntity(module.ParentId);
                if (parentOrg != null)
                {
                    cascadeId = parentOrg.CascadeId + "." + currentCascadeId;
                    module.ParentName = parentOrg.Name;
                }
                else
                {
                    throw new Exception("未能找到该组织的父节点信息");
                }
            }
            else
            {
                cascadeId = "0." + currentCascadeId;
                module.ParentName = "根节点";
            }
            module.CascadeId = cascadeId;
        }

        #endregion 私有方法

    }
}
